package com.atguigu.tingshu.user.listener;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.constant.TingShuMqConstants;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.service.RabbitmqService;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.vo.base.user.*;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.rabbitmq.client.Channel;
import jakarta.annotation.Resource;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.List;

@Component
public class UserListener {
    @Resource
    private UserPaidTrackMapper userPaidTrackMapper;
    @Resource
    private UserPaidAlbumMapper userPaidAlbumMapper;
    @Resource
    private VipServiceConfigMapper vipServiceConfigMapper;
    @Resource
    private UserVipServiceMapper userVipServiceMapper;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private RabbitmqService rabbitmqService;
    @Resource
    private TrackInfoFeignClient trackInfoFeignClient;

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = TingShuMqConstants.USER_EXCHANGE, type = ExchangeTypes.TOPIC, ignoreDeclarationExceptions = "ture"),
            value = @Queue(value = TingShuMqConstants.USER_RECORD_QUEUE),
            key = TingShuMqConstants.USER_RECORD_RK
    ))
    public void userRecordListener(String json, Channel channel, Message message) throws IOException {
        if (StringUtils.isBlank(json)) {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            return;
        }
        UserPaidRecordVo userPaidRecordVo = JSON.parseObject(json, UserPaidRecordVo.class);
        Long userId = userPaidRecordVo.getUserId();
        String orderNo = userPaidRecordVo.getOrderNo();
        List<Long> itemIdList = userPaidRecordVo.getItemIdList();
        try {
            switch (userPaidRecordVo.getItemType()) {
                case SystemConstant.ORDER_ITEM_TYPE_ALBUM -> {
                    //幂等性校验
                    UserPaidAlbum userPaidAlbum = this.userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getOrderNo, orderNo));
                    if (userPaidAlbum != null) {
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                        return;
                    }
                    //保存专辑购买行为
                    userPaidAlbum = new UserPaidAlbum();
                    userPaidAlbum.setOrderNo(orderNo);
                    userPaidAlbum.setUserId(userId);
                    userPaidAlbum.setAlbumId(itemIdList.get(0));
                    this.userPaidAlbumMapper.insert(userPaidAlbum);
                    //发送消息，保存专辑购买的统计信息
                    this.rabbitmqService.sendMqMsg(TingShuMqConstants.USER_EXCHANGE, TingShuMqConstants.PAID_STAT_RK, orderNo);
                }
                case SystemConstant.ORDER_ITEM_TYPE_TRACK -> {
                    //幂等性校验
                    Long count = this.userPaidTrackMapper.selectCount(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getOrderNo, orderNo));
                    if (count > 0) {
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                        return;
                    }
                    //获取声音的信息
                    Result<TrackInfo> trackInfoResult = this.trackInfoFeignClient.getTrackInfo(itemIdList.get(0));
                    Assert.notNull(trackInfoResult, "保存声音购买行为时，获取声音信息失败！");
                    TrackInfo trackInfo = trackInfoResult.getData();
                    //保存声音的购买行为
                    itemIdList.forEach(itemId -> {
                        UserPaidTrack userPaidTrack = new UserPaidTrack();
                        userPaidTrack.setOrderNo(orderNo);
                        userPaidTrack.setUserId(userId);
                        userPaidTrack.setAlbumId(trackInfo.getAlbumId());
                        userPaidTrack.setTrackId(itemId);
                        this.userPaidTrackMapper.insert(userPaidTrack);
                    });
                    //发送消息，保存声音购买的统计信息和专辑的统计信息
                    this.rabbitmqService.sendMqMsg(TingShuMqConstants.USER_EXCHANGE, TingShuMqConstants.PAID_STAT_RK, orderNo);
                }
                case SystemConstant.ORDER_ITEM_TYPE_VIP -> {
                    //幂等性校验
                    UserVipService userVipService = this.userVipServiceMapper.selectOne(new LambdaQueryWrapper<UserVipService>().eq(UserVipService::getOrderNo, orderNo));
                    if (userVipService != null) {
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                        return;
                    }
                    //记录VIP的购买记录
                    //获取购买的套餐
                    VipServiceConfig vipServiceConfig = this.vipServiceConfigMapper.selectById(itemIdList.get(0));
                    //判断用户的vip的状态
                    UserInfo userInfo = this.userInfoMapper.selectById(userId);
                    userVipService = new UserVipService();
                    userVipService.setOrderNo(orderNo);
                    userVipService.setUserId(userId);
                    LocalDateTime startTime = LocalDateTime.now().plusHours(8);
                    LocalDateTime expireTime = null;
                    if (userInfo.getIsVip() == 1 && userInfo.getVipExpireTime().after(new Date())) {
                        startTime = LocalDateTime.fromDateFields(userInfo.getVipExpireTime());
                        expireTime = startTime.plusMonths(vipServiceConfig.getServiceMonth());
                    } else {
                        expireTime = startTime.plusMonths(vipServiceConfig.getServiceMonth()).minusDays(1);
                        //非vip或者过期vip则修改vip状态及过期时间
                        userInfo.setIsVip(1);
                    }
                    userVipService.setStartTime(startTime.toDate());
                    userVipService.setExpireTime(expireTime.toDate());
                    this.userVipServiceMapper.insert(userVipService);
                    //修改用户的vip过期时间
                    userInfo.setVipExpireTime(expireTime.toDate());
                    this.userInfoMapper.updateById(userInfo);
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            if (message.getMessageProperties().getRedelivered()) {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }
    }


    public static void main(String[] args) {
        System.out.println(new Date());
        System.out.println(LocalDate.now().toDate());
        System.out.println(LocalDateTime.now().toDate());
    }
}
